package org.bbmall.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.bbmall.bean.sales.AdsInventoryAlert;
import org.bbmall.bean.sales.AdsPromotionEffect;
import org.bbmall.bean.sales.AdsRecentSales;
import org.bbmall.bean.sales.AdsTodayKpi;
import org.bbmall.dao.*;
import org.bbmall.dto.sales.*;
import org.bbmall.service.IAnalysisService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 销售分析业务服务实现类
 */
@Service
@RequiredArgsConstructor
public class AnalysisServiceImpl implements IAnalysisService {

    private final AdsTodayKpiMapper todayKpiMapper;
    private final AdsHotCategoryMapper hotCategoryMapper;
    private final AdsInventoryAlertMapper inventoryAlertMapper;
    private final AdsPromotionEffectMapper promotionEffectMapper;
    private final AdsRecentSalesMapper recentSalesMapper;

    /**
     * 获取仪表板所有数据
     */
    @Override
    public SalesDashboardDataDTO getDashboardData(LocalDate today) {

        LocalDate yesterday = today.minusDays(1);
        LocalDate lastWeekSameDay = today.minusWeeks(1);

        SalesDashboardDataDTO dashboardData = new SalesDashboardDataDTO();

        // 1. 设置今日核心指标
        dashboardData.setTodayKpi(buildTodayKpiDTO(today, yesterday, lastWeekSameDay));

        // 2. 设置热销商品分类
        dashboardData.setHotCategories(buildHotCategoriesDTO(today));

        // 3. 设置本周销售趋势
        dashboardData.setWeeklySalesTrend(buildWeeklySalesTrend(today));

        // 4. 设置库存预警
        dashboardData.setInventoryAlerts(buildInventoryAlertsDTO(today));

        // 5. 设置促销活动效果
        dashboardData.setPromotionEffects(buildPromotionEffectsDTO(today));

        // 6. 设置实时销售流水
        dashboardData.setRecentSales(buildRecentSalesDTO(10));

        return dashboardData;
    }

    /**
     * 构建今日核心指标DTO
     */
    private TodayKpiDTO buildTodayKpiDTO(LocalDate today, LocalDate yesterday, LocalDate lastWeekSameDay) {
        TodayKpiDTO kpiDTO = new TodayKpiDTO();

        // 获取今日数据
        AdsTodayKpi todayData = getTodayKpiByDate(today);
        if (todayData != null) {
            kpiDTO.setTodaySalesAmount(todayData.getTodaySalesAmount());
            kpiDTO.setTodayOrderCount(todayData.getTodayOrderCount());
            kpiDTO.setTodayCustomerCount(todayData.getTodayCustomerCount());
            kpiDTO.setAvgCustomerSpent(todayData.getAvgCustomerSpent());
        } else {
            // 如果没有今日数据，设置默认值
            kpiDTO.setTodaySalesAmount(BigDecimal.ZERO);
            kpiDTO.setTodayOrderCount(0L);
            kpiDTO.setTodayCustomerCount(0L);
            kpiDTO.setAvgCustomerSpent(BigDecimal.ZERO);
        }

        // 计算销售总额相比昨日变化率
        AdsTodayKpi yesterdayData = getTodayKpiByDate(yesterday);
        kpiDTO.setSalesAmountChangeRate(calculateChangeRate(
                todayData != null ? todayData.getTodaySalesAmount() : BigDecimal.ZERO,
                yesterdayData != null ? yesterdayData.getTodaySalesAmount() : BigDecimal.ZERO
        ));

        // 计算订单总数相比昨日变化率
        kpiDTO.setOrderCountChangeRate(calculateChangeRate(
                todayData != null ? BigDecimal.valueOf(todayData.getTodayOrderCount()) : BigDecimal.ZERO,
                yesterdayData != null ? BigDecimal.valueOf(yesterdayData.getTodayOrderCount()) : BigDecimal.ZERO
        ));

        // 计算客流量相比昨日变化率
        kpiDTO.setCustomerCountChangeRate(calculateChangeRate(
                todayData != null ? BigDecimal.valueOf(todayData.getTodayCustomerCount()) : BigDecimal.ZERO,
                yesterdayData != null ? BigDecimal.valueOf(yesterdayData.getTodayCustomerCount()) : BigDecimal.ZERO
        ));

        // 计算平均客单价相比上周变化率
        AdsTodayKpi lastWeekData = getTodayKpiByDate(lastWeekSameDay);
        kpiDTO.setAvgSpentChangeRate(calculateChangeRate(
                todayData != null ? todayData.getAvgCustomerSpent() : BigDecimal.ZERO,
                lastWeekData != null ? lastWeekData.getAvgCustomerSpent() : BigDecimal.ZERO
        ));

        return kpiDTO;
    }

    /**
     * 构建热销商品分类DTO
     */
    private List<HotCategoryDTO> buildHotCategoriesDTO(LocalDate statDate) {
        // 从ads_inventory_alert表获取库存数据
        QueryWrapper<AdsInventoryAlert> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate);
        List<AdsInventoryAlert> inventoryAlerts = inventoryAlertMapper.selectList(queryWrapper);

        // 按商品名称分组统计库存（这里假设商品名称包含类别信息）
        // 在实际应用中，可能需要根据商品名称映射到类别
        return inventoryAlerts.stream()
                .map(alert -> {
                    HotCategoryDTO dto = new HotCategoryDTO();
                    // 这里简化处理，直接使用商品名称作为类别名称
                    // 实际应用中可能需要根据商品名称解析出类别
                    dto.setCategoryName(alert.getProductName());
                    dto.setStockCount(alert.getCurrentStock());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建本周销售趋势数据
     */
    private List<BigDecimal> buildWeeklySalesTrend(LocalDate today) {
        LocalDate startOfWeek = today.minusDays(6); // 最近7天

        QueryWrapper<AdsTodayKpi> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("stat_date", startOfWeek, today)
                .orderByAsc("stat_date");

        List<AdsTodayKpi> weeklyData = todayKpiMapper.selectList(queryWrapper);

        // 提取销售额数据
        return weeklyData.stream()
                .map(AdsTodayKpi::getTodaySalesAmount)
                .collect(Collectors.toList());
    }

    /**
     * 构建库存预警DTO
     */
    private List<InventoryAlertDTO> buildInventoryAlertsDTO(LocalDate statDate) {
        QueryWrapper<AdsInventoryAlert> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate)
                .orderByAsc("alert_level") // 按预警级别排序
                .orderByAsc("current_stock"); // 库存少的排在前面

        List<AdsInventoryAlert> alerts = inventoryAlertMapper.selectList(queryWrapper);

        return alerts.stream()
                .map(alert -> {
                    InventoryAlertDTO dto = new InventoryAlertDTO();
                    dto.setProductName(alert.getProductName());
                    dto.setStockCount(alert.getCurrentStock());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建促销活动效果DTO
     */
    private List<PromotionEffectDTO> buildPromotionEffectsDTO(LocalDate statDate) {
        QueryWrapper<AdsPromotionEffect> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate)
                .orderByDesc("sales_growth_percent");

        List<AdsPromotionEffect> effects = promotionEffectMapper.selectList(queryWrapper);

        return effects.stream()
                .map(effect -> {
                    PromotionEffectDTO dto = new PromotionEffectDTO();
                    dto.setPromotionName(effect.getPromotionType());
                    dto.setGrowthPercent(effect.getSalesGrowthPercent());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建实时销售流水DTO
     */
    private List<RecentSalesDTO> buildRecentSalesDTO(int limit) {
        QueryWrapper<AdsRecentSales> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("sale_time")
                .last("LIMIT " + limit);

        List<AdsRecentSales> recentSales = recentSalesMapper.selectList(queryWrapper);

        return recentSales.stream()
                .map(sale -> {
                    RecentSalesDTO dto = new RecentSalesDTO();
                    dto.setOrderTime(sale.getSaleTime());
                    // 生成格式化的订单ID（根据实际需求调整）
                    dto.setOrderId("OR" + sale.getSaleTime().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + String.format("%03d", sale.getId() % 1000));
                    dto.setOrderAmount(sale.getSalesAmount());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 根据日期获取今日核心指标
     */
    private AdsTodayKpi getTodayKpiByDate(LocalDate date) {
        QueryWrapper<AdsTodayKpi> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", date);
        return todayKpiMapper.selectOne(queryWrapper);
    }

    /**
     * 计算变化率（百分比）
     * 公式：(当前值 - 基准值) / 基准值 * 100
     */
    private BigDecimal calculateChangeRate(BigDecimal currentValue, BigDecimal baseValue) {
        if (baseValue == null || baseValue.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }

        return currentValue.subtract(baseValue)
                .divide(baseValue, 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
    }
}